﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{
    public struct VertexPositionColorNormal
    {
        public Vector3 Position;
        public Color Color;
        public Vector3 Normal;

        public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(
            new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
            new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 0),
            new VertexElement(sizeof(float) * 3 + 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
        );
    }

    public class Game8 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        GraphicsDevice device;

        Effect effect;
        VertexPositionColorNormal[] vertices;
        Matrix viewMatrix;
        Matrix projectionMatrix;

        public Game8()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 500;
            graphics.PreferredBackBufferHeight = 500;
            graphics.IsFullScreen = false;
            graphics.ApplyChanges();
            Window.Title = "Riemer's XNA Tutorials -- 3D Series 1";

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            device = graphics.GraphicsDevice;

            effect = Content.Load<Effect>("effects");
            SetUpCamera();

            SetUpVertices();
        }

        protected override void UnloadContent()
        {
        }

        private void SetUpVertices()
        {
            vertices = new VertexPositionColorNormal[6];

            vertices[0].Position = new Vector3(0f, 0f, 50f);
            vertices[0].Color = Color.Blue;
            vertices[0].Normal = new Vector3(0, 0, 1);
            vertices[1].Position = new Vector3(50f, 0f, 0f);
            vertices[1].Color = Color.Blue;
            vertices[1].Normal = new Vector3(1, 0, 1);
            vertices[2].Position = new Vector3(0f, 50f, 50f);
            vertices[2].Color = Color.Blue;
            vertices[2].Normal = new Vector3(0, 0, 1);

            vertices[3].Position = new Vector3(-50f, 0f, 0f);
            vertices[3].Color = Color.Blue;
            vertices[3].Normal = new Vector3(-1, 0, 1);
            vertices[4].Position = new Vector3(0f, 0f, 50f);
            vertices[4].Color = Color.Blue;
            vertices[4].Normal = new Vector3(0, 0, 1);
            vertices[5].Position = new Vector3(0f, 50f, 50f);
            vertices[5].Color = Color.Blue;
            vertices[5].Normal = new Vector3(0, 0, 1);

            for (int i = 0; i < vertices.Length; ++i)
                vertices[i].Normal.Normalize();
        }

        private void SetUpCamera()
        {
            viewMatrix = Matrix.CreateLookAt(new Vector3(0, -40, 100), new Vector3(0, 50, 0), new Vector3(0, 1, 0));
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 300.0f);
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            device.Clear(Color.Black);

            RasterizerState rs = new RasterizerState();
            rs.CullMode = CullMode.None;
            device.RasterizerState = rs;

            effect.CurrentTechnique = effect.Techniques["Colored"];
            effect.Parameters["xView"].SetValue(viewMatrix);
            effect.Parameters["xProjection"].SetValue(projectionMatrix);
            effect.Parameters["xWorld"].SetValue(Matrix.Identity);
            effect.Parameters["xEnableLighting"].SetValue(true);

            Vector3 lightDirection = new Vector3(0.5f, 0f, -1.0f);
            lightDirection.Normalize();
            effect.Parameters["xLightDirection"].SetValue(lightDirection);

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();

                device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 2, VertexPositionColorNormal.VertexDeclaration);
            }

            base.Draw(gameTime);
        }
    }
}